package poo.alberi;

import java.util.ArrayList;

public class TreeUtil<E> {
	
	public void printInOrder(BTree<E> T) {
		printInOrder((BNode<E>) T.root());
	}

	private void printInOrder(BNode<E> v) {
		if (v.getLeft() != null)
			printInOrder(v.getLeft());
		System.out.print(v.getElement() + " ");
		if (v.getRight() != null)
			printInOrder(v.getRight());
	}

	public void printPreOrder(Tree<E> T) {
		printPreOrder(T.root());
	}

	private void printPreOrder(Nodo<E> v) {
		if (v.getParent() == null)
			System.out.print(v.getElement());
		else
			System.out.print(" " + v.getElement());
		for (Nodo<E> w : v.getChildren())
			printPreOrder(w);
		if (v.getParent() == null)
			System.out.println();
	}

	public Iterable<Nodo<E>> visitPostOrder(Tree<E> T) {
		return visitPostOrder(T.root(), new ArrayList<Nodo<E>>());
	}

	private Iterable<Nodo<E>> visitPostOrder(Nodo<E> v, ArrayList<Nodo<E>> l) {
		for (Nodo<E> w : v.getChildren())
			l = (ArrayList<Nodo<E>>) visitPostOrder(w, l);
		l.add(v);
		return l;
	}

	public int depth(Tree<E> T, Nodo<E> v) {
		if (T.isRoot(v))
			return 0;
		return 1 + depth(T, v.getParent());
	}

	public int height(Tree<E> T) {
		return height(T, T.root());
	}

	private int height(Tree<E> T, Nodo<E> v) {
		if (T.isExternal(v))
			return 0;
		int h = 0;
		for (Nodo<E> w : T.children(v))
			h = Math.max(h, height(T, w));
		return 1 + h;
	}

	public void stampa(Tree<E> tree) {
		stampa(tree.root(), 0);
	}

	private void stampa(Nodo<E> v, int level) {
		if (v == null)
			return;
		for (int i = 0; i < level - 1; i++) {
			System.out.print("   ");
		}
		if (level > 0)
			System.out.print(" |--");
		System.out.println(v.getElement());
		for (Nodo<E> children : v.getChildren()) {
			stampa(children, level + 1);
		}
	}
}
